﻿////////////////////////////////////////////////////////////////
///
/// File: ClonableSkeleton.cs
/// Author: Lucio Davide Spano
/// Last update: 27 July 2012
/// Description: This class extends the MS Kinect Skeleton object
///              with clone methods, used in order to buffer
///              feature changes.
/// To do: 
/// ------------------------------------------------------------
/// Copyright (c) 2012 Lucio Davide Spano 
///                     (lucio.davide.spano@isti.cnr.it)
/// 
/// The use and distribution terms for this software are 
/// contained in the file named license.txt, which can be found 
/// in the root of this distribution.
/// By using this software in any fashion, you are agreeing to 
/// be bound by the terms of this license.
///
/// You must not remove this notice, or any other, from this
/// software.
/// ------------------------------------------------------------
////////////////////////////////////////////////////////////////


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Kinect;

namespace BodyGestIT
{
    public class ClonableSkeleton : Skeleton
    {
        private volatile bool _right, _left = false;
        public bool LeftHandOpen
        {
            get { return _left; }
            protected set { this._left = value; }
        }
        public bool RightHandOpen
        {
            get { return _right; }
            protected set { this._right = value; }
        }
        public bool[] JointChanged { get; protected set; }
        public const double threshold = 0.001;


        public ClonableSkeleton()
            : base()
        {
            this.JointChanged = new bool[Joints.Count + 2];
        }

        public void UpdateFromSkeleton(Skeleton s)
        {
            // updating position
            SkeletonPoint p = new SkeletonPoint();
            p.X = s.Position.X;
            p.Y = s.Position.Y;
            p.Z = s.Position.Z;
            this.Position = new SkeletonPoint();

            // updating tracking id
            this.TrackingId = s.TrackingId;

            // updating clippingEdges
            this.ClippedEdges = s.ClippedEdges;


            // updating joints
            foreach (Joint j in s.Joints)
            {
                SkeletonPoint jointPos = new SkeletonPoint();
                if (Math.Abs(this.Joints[j.JointType].Position.X - j.Position.X) > threshold ||
                    Math.Abs(this.Joints[j.JointType].Position.Y - j.Position.Y) > threshold ||
                    Math.Abs(this.Joints[j.JointType].Position.Z - j.Position.Z) > threshold)
                {
                    JointChanged[(int)j.JointType] = true;
                }
                else
                {
                    JointChanged[(int)j.JointType] = false;
                }
                jointPos.X = j.Position.X;
                jointPos.Y = j.Position.Y;
                jointPos.Z = j.Position.Z;
                Joint clone = this.Joints[j.JointType];
                clone.Position = jointPos;
                //clone.JointType = j.JointType;
                clone.TrackingState = j.TrackingState;
                this.Joints[j.JointType] = clone;
            }
        }


        public void UpdateFromSkeleton(ClonableSkeleton s)
        {
            UpdateFromSkeleton((Skeleton)s);

            JointChanged[this.Joints.Count] = this.RightHandOpen != s.RightHandOpen;
            JointChanged[this.Joints.Count + 1] = this.LeftHandOpen != s.LeftHandOpen;

            if (this.LeftHandOpen != s.LeftHandOpen)
            {
                Console.WriteLine("open left");
            }

            this.LeftHandOpen = s.LeftHandOpen;
            this.RightHandOpen = s.RightHandOpen;
            //Console.WriteLine("right hand change" + RightHandOpen);
        }


        internal void SetHandOpen(bool leftHand, bool rightHand)
        {

            JointChanged[this.Joints.Count] = this.RightHandOpen != rightHand;
            JointChanged[this.Joints.Count + 1] = this.LeftHandOpen != leftHand;
            if (this.LeftHandOpen != leftHand)
            {
                Console.WriteLine("open left");
            }
            //Console.WriteLine(" right hand update from {0} to {1} ", RightHandOpen, rightHand);
            this.LeftHandOpen = leftHand;
            this.RightHandOpen = rightHand;

            //Console.WriteLine("right hand change" + RightHandOpen);
        }
    }
}
